/**
 * 北京钉图互动科技 all right reserver
 */
package com.impress.commons.exception.rpc;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.impress.commons.exception.ErrorResponse;
import com.impress.commons.exception.RemoteCallException;
import com.impress.commons.exception.translate.ErrorResponseTranslatable;
import com.impress.commons.vo.annotation.RemoteService;

/**
 * 拦截所有{@link RemoteService}注解类的异常
 * <p>
 * 注：{@link RemoteService}注解只能用在类，而不能用在接口上
 * 
 * @author Wangyi
 * @since 2016年6月24日
 */
@Aspect
public class RemoteCallExceptionAspect {

	private static final Logger log = LoggerFactory.getLogger(RemoteCallExceptionAspect.class);

	private final ErrorResponseTranslatable errorResponseTranslator;

	/**
	 * @param errorResponseTranslator
	 */
	public RemoteCallExceptionAspect(ErrorResponseTranslatable errorResponseTranslator) {
		super();
		if (errorResponseTranslator == null) {
			throw new NullPointerException("the 'errorResponseTranslator' argument must not be null");
		}
		this.errorResponseTranslator = errorResponseTranslator;
	}

	@AfterThrowing(pointcut = "remoteServicePointcut()", throwing = "ex")
	public void methodCallAfterThrowing(JoinPoint jp, Throwable ex) {
		log.error("调用对象{}的方法{}异常", jp.getTarget(), jp.getSignature(), ex);
		ErrorResponse errResp = this.errorResponseTranslator.translate(ex);
		throw new RemoteCallException(errResp);
	}

	@Pointcut("within(@com.impress.commons.vo.annotation.RemoteService *)")
	private void remoteServicePointcut() {
		// nothing
	}

}
